﻿#pragma once

#include "Env.h"
#include "Validation.h"

#define FUNCTION_NAME(uniq) BUILTIN_##uniq
#define HANDLER_NAME(uniq) HANDLER_##uniq
#define BUILTIN_DEF(uniq, symbol)                                                                                                             \
  static BuiltInFuncType::ApplyFunc FUNCTION_NAME(uniq);                                                                                      \
  static StaticList<ValPtr>::Node HANDLER_NAME(uniq)(s_builtInList, symbol, ValPtr(new BuiltInFuncType(symbol, FUNCTION_NAME(uniq)))); \
  ValPtr FUNCTION_NAME(uniq)(const std::string &name, ListPtr args)

#define BUILTIN(symbol) BUILTIN_DEF(__LINE__, symbol)

#define ARG_COUNT_IS(expectArgc) Lisp::CheckArgsIs(name, args->Size(), expectArgc)
#define ARG_COUNT_BETWEEN(min, max) Lisp::CheckArgsBetween(name, args->Size(), min, max)
#define ARG_COUNT_AT_LEAST(min) Lisp::CheckArgsAtLeast(name, args->Size(), min)

#define ARG(idx, Type, name) Type *name = VALUE_CAST(Type, args->At(idx));

namespace Lisp
{
  void InitNativeBuiltIns(EnvPtr env);
}
